package fun.ticsmyc.multiThread.流控;

import java.util.concurrent.atomic.AtomicLong;

public class 漏桶 {
    //桶容量（最大请求量）
    private final long capacity;

    //水流量 （请求/秒）
    private final long leakRate;

    //当前请求数 （待处理请求数
    private AtomicLong water;

    //上次漏水时间戳
    private long lastLeakTime;

    public 漏桶(long capacity, long leakRate) {
        this.capacity = capacity;
        this.leakRate = leakRate;
        this.water = new AtomicLong(0);
        this.lastLeakTime = System.currentTimeMillis();
    }
    public synchronized boolean tryPass(){
        leakWater();

        if(water.get() < capacity){
            water.incrementAndGet();
            return true;
        }
        return false;
    }

    private void leakWater() {
        long now = System.currentTimeMillis();
        long elapsedMs = now - this.lastLeakTime;
        if(elapsedMs >0){
            long leaked = (long)(elapsedMs * leakRate /1000);
            if (leaked > 0){
                water.updateAndGet(cur -> Math.max(0,cur-leaked));
                lastLeakTime = now;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        漏桶 leakBucket = new 漏桶(5, 1);

        for (int i = 0; i < 15; i++) {
            if(leakBucket.tryPass()){
                System.out.println("请求"+i+"通过");
            }else{
                System.out.println("限流"+i);
            }
            Thread.sleep(200);
        }

    }


}
